package com.hzya.frame.utils.help;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;

import com.hzya.frame.system.user.entity.UserEntity;

/***
 * BeanHelper
 * 
 * @author 王行理 2015-10-21
 *
 */
public class BeanHelper {
	private final static Log log = LogFactory.getLog(BeanHelper.class);

	public static Map fieldMap = new HashMap();

	// 这个类不能实例化
	private BeanHelper() {
	}

	/***
	 * object是否为空
	 * 
	 * @param object
	 * @param ignore
	 * @return
	 */
	public static boolean isEmpty(Object object, String ignore) {
		if (object == null) {
			return true;
		}
		if (object instanceof Map) {
			if (((Map) object).size() == 0) {
				return true;
			}
			Iterator keyIter = ((Map) object).keySet().iterator();
			while (keyIter.hasNext()) {
				Object key = keyIter.next();
				Object value = ((Map) object).get(key);
				if (value != null && !"".equals(value)) {
					boolean isIgnore = false;
					if (ignore != null && !"".equals(ignore)) {
						if (ignore.indexOf(",") != -1) {
							String[] ignores = ignore.split(",");
							for (int j = 0; j < ignores.length; j++) {
								if (ignores[j].equals(key)) {
									isIgnore = true;
									continue;
								}
							}
						} else {
							if (key.equals(ignore)) {
								isIgnore = true;
							}
						}
						if (isIgnore) {
							continue;
						} else {
							return false;
						}
					} else {
						return false;
					}
				}
			}
			return true;
		}
		Field[] fields = getFields(object.getClass());
		boolean isEmpty = true;
		for (int i = 0; i < fields.length; i++) {
			try {
				Field field = fields[i];
				if (!field.isAccessible()) {
					field.setAccessible(true);
				}
				if (ignore != null && !"".equals(ignore)) {
					boolean isIgnore = false;
					if (ignore.indexOf(",") != -1) {
						String[] ignores = ignore.split(",");
						for (int j = 0; j < ignores.length; j++) {
							if (ignores[j].equals(field.getName())) {
								isIgnore = true;
								continue;
							}
						}
					} else {
						if (field.getName().equals(ignore)) {
							isIgnore = true;
							continue;
						}
					}
					if (isIgnore) {
						continue;
					}
				}
				if (field.getType().equals(List.class)) {
					continue;
				}
				if (!isPrimitiveType(field.getType())) {
					String fieldName = field.getName();
					String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
					String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
					try {
						Method getMethod = object.getClass().getDeclaredMethod(getMethodName, null);
						Object value = getMethod.invoke(object, null);
						if (value != null && !"".equals(value)) {
							if (value.getClass().getName().indexOf("EnhancerByCGLIB") != -1
									|| !isEmpty(value, ignore)) {
								isEmpty = false;
								break;
							}
						}
					} catch (NoSuchMethodException e) {
						log.info(e);
					} catch (InvocationTargetException e) {
						log.info(e);
					}
				} else {
					Object value = field.get(object);
					if (value != null) {
						isEmpty = false;
						break;
					}
				}
			} catch (IllegalAccessException e) {
				log.info(e);
			}
		}
		return isEmpty;
	}

	/***
	 * copy新的list
	 * 
	 * @param list
	 * @return
	 */
	public static List copyNewList(List list) {
		List newList = new ArrayList();
		if (list == null || list.size() == 0) {
			return newList;
		}
		for (int i = 0; i < list.size(); i++) {
			newList.add(list.get(i));
		}
		return newList;
	}

	/**
	 * 获取object中所有的字段和字段值
	 * 
	 * @param contextMap
	 *            结果集合
	 * @param object
	 *            目标
	 */
	public static void putAllFieldValue(Map contextMap, Object object) {
		Field[] fields = getFields(object.getClass());
		for (int i = 0; i < fields.length; i++) {
			try {
				fields[i].setAccessible(true);
				contextMap.put(fields[i].getName(), fields[i].get(object));
			} catch (IllegalArgumentException e) {
				throw new RuntimeException(e);
			} catch (IllegalAccessException e) {
				throw new RuntimeException(e);
			}
		}
	}

	/**
	 * 获取类的SimpleName
	 * 
	 * @param clazz
	 * @return
	 */
	public static String getSimpleName(Class clazz) {
		String name = clazz.getName();
		if (name.indexOf(".") == -1) {
			return name;
		}
		return name.substring(name.lastIndexOf(".") + 1);
	}

	/**
	 * 类中是否包含某个字段
	 * 
	 * @param clazz
	 * @param propertyName
	 * @return
	 */
	public static boolean hasField(Class clazz, String propertyName) {
		return getField(clazz, propertyName) != null;
	}

	/***
	 * 获取类的字段的类型
	 * 
	 * @param clazz
	 * @param propertyName
	 * @return
	 */
	public static Class getFieldType(Class clazz, String propertyName) {
		if (!hasField(clazz, propertyName)) {
			return null;
		}
		return getField(clazz, propertyName).getType();
	}

	/***
	 * 查找类中的字段
	 * 
	 * @param clazz
	 * @param propertyName
	 * @return
	 */
	public static Field getField(Class clazz, String propertyName) {
		Field[] fields = getFields(clazz);
		for (int i = 0; i < fields.length; i++) {
			Field field = fields[i];
			if (field.getName().equals(propertyName)) {
				return field;
			}
		}
		return null;
	}

	/**
	 * 得到class的所有字段集合
	 * 
	 * @param clazz
	 * @return
	 */
	public static Field[] getFields(Class clazz) {
		String key = clazz.getName();
		if (fieldMap.containsKey(key)) {
			return (Field[]) fieldMap.get(key);
		} else {
			Field[] fields = clazz.getDeclaredFields();
			synchronized (fieldMap) {
				fieldMap.put(key, fields);
			}
			return fields;
		}

	}

	/**
	 * 获得两个类的公共字段
	 * 
	 * @param sourClass
	 * @param toClass
	 * @return
	 * @throws IntrospectionException
	 */
	public static List<PropertyDescriptor> getIntersectFields(Class sourClass, Class toClass) throws Exception {

		BeanInfo sourceBeanInfo = Introspector.getBeanInfo(sourClass);
		PropertyDescriptor[] sourceProperties = sourceBeanInfo.getPropertyDescriptors();
		BeanInfo toBeanInfo = Introspector.getBeanInfo(toClass);
		PropertyDescriptor[] toproperties = toBeanInfo.getPropertyDescriptors();
		List<PropertyDescriptor> resultList = new LinkedList<PropertyDescriptor>();

		for (PropertyDescriptor toProperty : toproperties) {
			String toPropertyName = toProperty.getName();
			if (!toPropertyName.equals("class")) {
				for (PropertyDescriptor sourceProperty : sourceProperties) {
					String sourcePropertyName = sourceProperty.getName();
					if (toPropertyName.equals(sourcePropertyName)) {
						resultList.add(toProperty);
					}
				}
			}
		}

		return resultList;
	}

	/**
	 * 允许不同对象之间的拷贝
	 * 
	 * @param source
	 * @param to
	 * @return
	 * @throws Exception
	 */
	public static Object copyNotNullAllowDifferent(Object source, Object to) throws Exception {

		List<PropertyDescriptor> fields = getIntersectFields(source.getClass(), to.getClass());
		for (int i = 0; i < fields.size(); i++) {
			try {
				PropertyDescriptor field = fields.get(i);
				String fieldName = field.getName();
				Object value = PropertyUtils.getSimpleProperty(source, field.getName());
				if (null != value && !"".equals(value)) {
					PropertyUtils.setSimpleProperty(to, fieldName, value);
				}

			} catch (Exception e) {
				// pass
				e.printStackTrace();
				log.info(e);
			}
		}
		return to;
	}

	/**
	 * 得到bean的属性的字符串值，如果为null，转为''
	 * 
	 * @param propertyName
	 * @param bean
	 * @return
	 */
	public final static String getStringValueIfNullToEmpty(String propertyName, Object bean) {
		Object value = getPropertyValue(propertyName, bean);
		if (value == null) {
			return "";
		} else {
			return String.valueOf(value);
		}
	}

	/**
	 * 初始化bean的非基本类型(容器,自定义类型)
	 * 
	 * @param ob
	 * @param propertyName
	 */
	public static void initializeBeanProperty(Object ob, String propertyName) {
		Field field = getField(ob.getClass(), propertyName);
		if (field != null) {
			if (!isPrimitiveType(field.getType())) {// 非私有类型
				field.setAccessible(false);
				Class klass = field.getType();// 得到type的类
				if (klass.equals(List.class)) {
					setPropertyValue(ob, propertyName, new ArrayList());// 将ob中的propertyName赋值
					return;
				}
				if (klass.equals(ArrayList.class)) {
					setPropertyValue(ob, propertyName, new ArrayList());
					return;
				}
				if (klass.equals(LinkedList.class)) {
					setPropertyValue(ob, propertyName, new LinkedList());
					return;
				}
				if (klass.equals(Map.class)) {
					setPropertyValue(ob, propertyName, new HashMap());
					return;
				}
				if (klass.equals(HashMap.class)) {
					setPropertyValue(ob, propertyName, new HashMap());
					return;
				}
				if (klass.equals(Hashtable.class)) {
					setPropertyValue(ob, propertyName, new Hashtable());
					return;
				}
				try {
					/**
					 * 尝试默认构造函数初始化
					 */
					setPropertyValue(ob, propertyName, newInstance(klass));// 赋值的类型初始化
				} catch (Exception e) {// 出错了，好吧，那就把所有的构造函数一个个的尝试把，总有一个是可以的，否则，就是你的代码有问题了，eclipse早提醒你了，也不会编译成class文件了
					/**
					 * 检查构造函数
					 */
					Constructor[] constructors = klass.getDeclaredConstructors();// 获取构造函数列表
					if (constructors != null) {
						for (int i = 0; i < constructors.length; i++) {// 遍历
							Constructor constructor = (Constructor) constructors[i];
							/**
							 * 尝试用第一个有权限的构造函数初始化
							 */
							if (constructor.isAccessible()) {// 判断构造函数isAccessible
								try {
									setPropertyValue(ob, propertyName, constructor.newInstance(null));
									return;
								} catch (IllegalArgumentException e1) {
									throw new RuntimeException(e1);
								} catch (InstantiationException e1) {
									throw new RuntimeException(e1);
								} catch (IllegalAccessException e1) {
									throw new RuntimeException(e1);
								} catch (InvocationTargetException e1) {
									throw new RuntimeException(e1);
								}
							}
						}
					}
				}
			}
		}
	}

	/***
	 * 给对象的某个字段赋值
	 * 
	 * @param ob
	 * @param propertyName
	 * @param propertyValue
	 */
	public static void setPropertyValue(Object ob, String propertyName, Object propertyValue) {
		try {
			Field field = getField(ob.getClass(), propertyName);
			field.setAccessible(true);
			field.set(ob, propertyValue);
		} catch (SecurityException e) {
			throw new RuntimeException(e);
		} catch (IllegalArgumentException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}

	/***
	 * 给某个类的某个字段赋值，生成一堆的对象
	 * 
	 * @param properyValues
	 * @param klass
	 * @param propertyName
	 * @return
	 */
	public static List initializeList(Object[] properyValues, Class klass, String propertyName) {
		List list = new ArrayList();
		for (int i = 0; i < properyValues.length; i++) {
			Object bean = newInstance(klass);
			setPropertyValue(bean, propertyName, properyValues[i]);
			list.add(bean);
		}
		return list;
	}

	/**
	 * 对象初始化(只执行set函数)
	 * 
	 * @param ob
	 * @return
	 */
	public static Object initialize(Object ob) {
		Method[] methods = getMethods(ob.getClass());// 获取类名称，然后根据类，找到函数列表
		for (int i = 0; i < methods.length; i++) {
			String methodName = methods[i].getName();// 找到函数名称
			if (methodName.startsWith("set")) {// 找到set函数
				/**
				 * ok,标准的set函数
				 */
				Method setMethod = methods[i];// 找到函数
				Class[] klasss = setMethod.getParameterTypes();// 找到哦啊函数的参数类型
				if (klasss.length == 1) {// 如果只有一个参数，往下执行，如果超过一个参数，好吧，您不是标准的set函数
					/**
					 * 长度为1才是默认set函数
					 */
					Class klass = klasss[0];// 找到参数的类
					Object[] params = new Object[1];// 参数，只有一个
					if (String.class.equals(klass)) {// 如果是string类型
						params[0] = "A";
					} else if (Long.class.equals(klass)) {// 如果是Long
						/**
						 * +i 是为了区分如果有两个Long类型的值
						 * eg:双主键，因为要插入数据库，所以不能简单的'0'，否则会出错
						 */
						params[0] = new Long(i);
						// params[0] = new Long(System.currentTimeMillis() + i);
					} else if (Date.class.equals(klass)) {
						params[0] = new Date();
					} else if (Integer.class.equals(klass)) {
						params[0] = new Integer(0);
					} else if (Double.class.equals(klass)) {
						params[0] = new Double(0);
					} else if (List.class.equals(klass)) {
						params[0] = new ArrayList(0);
					} else if (klass.getClass().getName().equals("java.lang.Class")) {// 好吧，基础类型，既然是基础类型，不用初始化了，往下一个吧
						/**
						 * int等基本类型得到的class是java.lang.Class
						 */
						continue;
					} else {// 复杂类型，比如，自定义的类型，好吧，那就初始化吧
						// params[0] = initialize(newInstance(klass));
						params[0] = newInstance(klass);
					}
					try {
						setMethod.invoke(ob, params);// 调用obj的set函数吧，顺便加上参数。
					} catch (IllegalArgumentException e) {
						throw new RuntimeException(e);
					} catch (IllegalAccessException e) {
						throw new RuntimeException(e);
					} catch (InvocationTargetException e) {
						throw new RuntimeException(e);
					}
				}
			}
		}
		return ob;
	}

	private static Map methodMap = new HashMap();

	/***
	 * 判断是否有某个函数
	 * 
	 * @param clazz
	 * @param methodName
	 * @return
	 */
	public static boolean hasMethod(Class clazz, String methodName) {
		return getMethod(clazz, methodName) != null;
	}

	/***
	 * 判断是否有某个函数，不区分大小写
	 * 
	 * @param clazz
	 * @param methodName
	 * @return
	 */
	public static boolean hasMethodIgnoreCase(Class clazz, String methodName) {
		return getMethodIgnoreCase(clazz, methodName) != null;
	}

	/***
	 * 获取某个类中的函数名称为methodName的函数(不区分大小写)
	 * 
	 * @param clazz
	 * @param methodName
	 * @return
	 */
	public static Method getMethodIgnoreCase(Class clazz, String methodName) {
		Method[] methods = getMethods(clazz);
		for (int i = 0; i < methods.length; i++) {
			Method method = methods[i];
			if (method.getName().equalsIgnoreCase(methodName)) {
				return method;
			}
		}
		return null;
	}

	/***
	 * 获取某个类中的函数名称为methodName的函数
	 * 
	 * @param clazz
	 * @param methodName
	 * @return
	 */
	public static Method getMethod(Class clazz, String methodName) {
		Method[] methods = getMethods(clazz);
		for (int i = 0; i < methods.length; i++) {
			Method method = methods[i];
			if (method.getName().equals(methodName)) {// 只要找到一个就行了，可能会因为多态出现多个函数名一样的函数，不管他了
				return method;
			}
		}
		return null;
	}

	/***
	 * 获取类中名称为methodName的函数列表 多态
	 * 
	 * @param clazz
	 * @param methodName
	 * @return
	 */
	public static List getMethods(Class clazz, String methodName) {
		Method[] methods = getMethods(clazz);
		List list = new ArrayList();
		for (int i = 0; i < methods.length; i++) {
			Method method = methods[i];
			if (method.getName().equals(methodName)) {
				list.add(method);
			}
		}
		return list;
	}

	/***
	 * 获取所有的函数列表
	 * 
	 * @param clazz
	 * @return
	 */
	public static Method[] getMethods(Class clazz) {
		/**
		 * clazz.getName() 是object ??
		 */
		String key = clazz.getName();
		if (methodMap.get(key) == null) {
			List methodList = new ArrayList();
			while (!clazz.equals(Object.class)) {
				/**
				 * 包含超类的方法
				 */
				for (int i = 0; i < clazz.getMethods().length; i++) {
					methodList.add(clazz.getMethods()[i]);
				}
				clazz = clazz.getSuperclass();
			}
			Method[] methods = new Method[methodList.size()];
			for (int i = 0; i < methodList.size(); i++) {
				methods[i] = (Method) methodList.get(i);
			}
			synchronized (methodMap) {// 要同步锁锁住的，否则，大伙都写的话就乱套了
				methodMap.put(key, methods);
			}
		}
		return (Method[]) methodMap.get(key);
	}

	/***
	 * 获取函数名称列表(可能包含一样名字的哦，因为多态)
	 * 
	 * @param clazz
	 * @return
	 */
	public static List getMethodNameList(Class clazz) {
		Method[] methods = getMethods(clazz);
		List nameList = new ArrayList();
		for (int i = 0; i < methods.length; i++) {
			nameList.add(methods[i].getName());
		}
		return nameList;
	}

	/***
	 * 深度拷贝一个对象，这个非常有用
	 * 
	 * @param source
	 * @return
	 */
	public static Object copy(Object source) {
		if (source == null) {
			return null;
		}
		Object to = null;
		try {
			to = source.getClass().newInstance();// 和source一样的类型，来个实例吧
		} catch (Exception e) {
			throw new RuntimeException("class[" + source.getClass().getName() + " has'n no parameter constructor]");
		}
		Field[] fields = getFields(source.getClass());// 获取字段列表
		for (int i = 0; i < fields.length; i++) {
			try {
				Field field = fields[i];// 找到字段
				if (!field.isAccessible()) {// 无权限
					field.setAccessible(true);// 给他
				}
				if (field.getModifiers() != Modifier.PRIVATE && field.getModifiers() != Modifier.STATIC) {// public？protected。。。？
					/**
					 * 非private
					 */
					Object value = field.get(source);// 找到值
					if (value != null) {
						if (isPrimitiveType(value.getClass())) {// 基础类型？
							field.set(to, value);
						} else {
							Object newValue = copy(value);// 非基础类型？在copy当前的这个字段值吧
							field.set(to, newValue);// 赋值
						}
					}
				} else {// 私有类型
					if (isPrimitiveType(field.getType())) {// 基础类型？
						Object value = field.get(source);
						if (value != null) {
							field.set(to, value);// 赋值
						}
					} else {// 非基础类型？
						/**
						 * 检查是否有get函数
						 */
						String fieldName = field.getName();// 获取字段名
						String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
						String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
						try {
							Method getMethod = source.getClass().getDeclaredMethod(getMethodName, null);// 获取get函数
							Object value = getMethod.invoke(source, null);// 不带参数，调用吧，获取到值
							if (value == null) {
								continue;
							}
							Class[] params = { field.getType() };// 准备弄set了
							Object[] obs = new Object[1];// 就一个参数，
							if (isPrimitiveType(value.getClass())) {// 基础类型？
								obs[0] = value;
							} else {
								obs[0] = copy(value);// 非基础类型，好吧，深拷贝当前这个对象吧，知道这个对象拷贝完成，赋给参数
							}
							Method setMethod = source.getClass().getDeclaredMethod(setMethodName, params);// 调用set函数吧
							setMethod.invoke(to, obs);
						} catch (NoSuchMethodException e) {
							log.info(e);
						} catch (InvocationTargetException e) {
							log.info(e);
						}
					}
				}

			} catch (IllegalAccessException e) {
				log.info(e);
			}
		}
		return to;
	}

	public static <T> List<T> copyListNotNull(List sourceList, List<T> targetList, Class<T> targetClass)
			throws Exception {
		if (null != sourceList && 0 < sourceList.size()) {
			if (null == targetList) {
				targetList = new LinkedList();
			}
			for (Object tempObject : sourceList) {
				Object targetObj = targetClass.newInstance();
				BeanUtils.copyProperties(tempObject, targetObj);
				targetList.add((T) targetObj);
			}
		}
		return targetList;
	}

	/***
	 * 浅拷贝一个对象给另外一个对象
	 * 
	 * @param source
	 * @param to
	 */
	public static void copy(Object source, Object to) {
		if (source != null && to != null) {
			if (!source.getClass().equals(to.getClass())) {
				if (!source.getClass().getName().startsWith(to.getClass().getName())
						&& !to.getClass().getName().startsWith(source.getClass().getName())) {
					throw new RuntimeException(
							"copy的两个对象类型不一致,source(" + source.getClass() + "),to(" + to.getClass() + ")");
				}
			}
			Field[] fields = getFields(source.getClass());
			for (int i = 0; i < fields.length; i++) {
				try {
					Field field = fields[i];
					if (!field.isAccessible()) {
						field.setAccessible(true);
					}
					if (field.getModifiers() != 2) {
						/**
						 * 非private
						 */
						Object value = field.get(source);
						field.set(to, value);
					} else {
						/**
						 * 检查是否有get函数
						 */
						if (isPrimitiveType(field.getType())) {

							Object value = field.get(source);
							if (value != null) {
								field.set(to, value);
							}
						} else {
							String fieldName = field.getName();
							String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase()
									+ fieldName.substring(1);
							String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase()
									+ fieldName.substring(1);
							try {
								Method getMethod = source.getClass().getDeclaredMethod(getMethodName, null);
								Object value = getMethod.invoke(source, null);

								Class[] params = { field.getType() };
								Object[] obs = { value };
								Method setMethod = source.getClass().getDeclaredMethod(setMethodName, params);
								setMethod.invoke(to, obs);
							} catch (NoSuchMethodException e) {
								// pass\
								// throw new RuntimeException(e);
							} catch (InvocationTargetException e) {
								// pass
								throw new RuntimeException(e);
							}
						}
					}

				} catch (IllegalAccessException e) {
					// pass
					throw new RuntimeException(e);
				}
			}
		}
		/*
		 * try { BeanUtils.copyProperties(tobean, sourcebean); } catch
		 * (IllegalAccessException e) { throw new RuntimeException(e); } catch
		 * (InvocationTargetException e) { throw new RuntimeException(e); }
		 */
	}

	/***
	 * copy不为空的字段给另外一个对象，浅拷贝，慎用
	 * 
	 * @param source
	 * @param to
	 * @return
	 */
	public static Object copyNotNull(Object source, Object to) {
		if (source != null && to != null) {
			if (!source.getClass().equals(to.getClass())) {
				throw new RuntimeException(
						"copy的两个对象类型不一致,source(" + source.getClass() + "),to(" + to.getClass() + ")");
			}
			Field[] fields = getFields(source.getClass());// 获取字段列表
			for (int i = 0; i < fields.length; i++) {
				try {
					Field field = fields[i];
					if (!field.isAccessible()) {
						field.setAccessible(true);
					}
					if (field.getModifiers() != 2) {
						/**
						 * 非private
						 */
						Object value = field.get(source);
						if (value != null) {
							field.set(to, value);
						}
					} else {
						/**
						 * 检查是否有get函数
						 */
						if (isPrimitiveType(field.getType())) {// 如果为基础类型
							Object value = field.get(source);
							if (value != null) {
								field.set(to, value);
							}
						} else {
							String fieldName = field.getName();
							String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase()
									+ fieldName.substring(1);
							String setMethodName = "set" + fieldName.substring(0, 1).toUpperCase()
									+ fieldName.substring(1);
							try {
								Method getMethod = source.getClass().getDeclaredMethod(getMethodName, null);
								Object value = getMethod.invoke(source, null);
								if (value != null && (!"".equals(value))) {
									Class[] params = { field.getType() };
									Object[] obs = { value };
									Method setMethod = source.getClass().getDeclaredMethod(setMethodName, params);
									setMethod.invoke(to, obs);
								}
							} catch (NoSuchMethodException e) {
								// pass
								log.info(e);
							} catch (InvocationTargetException e) {
								// pass
								log.info(e);
							}
						}
					}

				} catch (IllegalAccessException e) {
					// pass
					e.printStackTrace();
					log.info(e);
				}
			}
		}
		return to;
	}

	/****
	 * copy不为null的基础属性给另外一个对象，浅拷贝
	 * 
	 * @param source
	 * @param to
	 * @return
	 */
	public static Object copyNotNullPrimitiveProperties(Object source, Object to) {
		if (source != null && to != null) {
			if (!source.getClass().equals(to.getClass())) {
				throw new RuntimeException("copy Error,source(" + source.getClass() + "),to(" + to.getClass() + ")");
			}
			Field[] fields = getFields(source.getClass());
			for (int i = 0; i < fields.length; i++) {
				try {
					Field field = fields[i];
					if (!field.isAccessible()) {
						field.setAccessible(true);
					}
					if (field.getModifiers() != 2) {

						Object value = field.get(source);
						if (value != null) {
							field.set(to, value);
						}
					} else {
						if (isPrimitiveType(field.getType())) {
							Object value = field.get(source);
							if (value != null) {
								field.set(to, value);
							}
						}
					}
				} catch (IllegalAccessException e) {
					// pass
					log.info(e);
				}
			}
		}
		return to;
	}

	/***
	 * 
	 * @param source
	 *            操作对象
	 * @return 返回Map(去掉了空字段)
	 * @throws IntrospectionException
	 * @throws IllegalAccessException
	 * @throws IllegalArgumentException
	 * @throws InvocationTargetException
	 */
	@SuppressWarnings("unchecked")
	public static Map<Object, Object> copyNotNull2Map(Object source)
			throws IntrospectionException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Map<Object, Object> map = null;
		if (source != null) {
			BeanInfo beanInfo = Introspector.getBeanInfo(source.getClass());
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (int i = 0; i < propertyDescriptors.length; i++) {
				PropertyDescriptor propertyDescriptor = propertyDescriptors[i];
				// 获取字段名称
				String name = propertyDescriptor.getName();
				// System.out.println(name);
				if (!name.equals("class")) {// 过滤Object掉内置的class字段
					Class<?> propertyType = propertyDescriptor.getPropertyType();
					if (isPrimitiveType(propertyType)) {// 基础类型
						Method readMethod = propertyDescriptor.getReadMethod();// 动态调用get函数
						if (readMethod != null) {
							Object value = readMethod.invoke(source, null);
							if (!(value == null || "".equals(value) || value.equals(0))) {
								if (Date.class.equals(propertyType)) {// 时间类型特殊处理
									String date_str = DateHelper.dateToString((Date) value, "yyyy-MM-dd HH:mm:ss");
									if (map == null) {
										map = new HashMap<Object, Object>();
									}
									map.put(name, date_str);
								} else {
									if (map == null) {
										map = new HashMap<Object, Object>();
									}
									map.put(name, value);
								}
							}
						}
					} else {// 非基本类型
						Method readMethod = propertyDescriptor.getReadMethod();
						if (readMethod != null) {
							Object value = readMethod.invoke(source, null);
							if (!(value == null || "".equals(value) || value.equals(0))) {// 有数据
								if (List.class.equals(propertyType)) {// 如果出现对象嵌套list嵌套
									List<Object> list = new ArrayList<Object>();
									for (Object _obj : (List<Object>) value) {
										Map<Object, Object> obj_map = copyNotNull2Map(_obj);
										list.add(obj_map);
									}
									if (map == null) {
										map = new HashMap<Object, Object>();
									}
									map.put(name, list);
								} else {
									Map<Object, Object> obj_map = copyNotNull2Map(value);
									if (obj_map != null) {
										if (map == null) {
											map = new HashMap<Object, Object>();
										}
										map.put(name, obj_map);
									}
								}
							}
						}
					}
				}
			}
		}
		return map;
	}

	/***
	 * 将数据字典中的空字符串去掉。
	 * 
	 * @param list
	 * @return
	 * @throws IntrospectionException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 * @throws IllegalAccessException
	 */
	public static List<Map<Object, Object>> getNoNull2Map(List<?> list) throws Exception {
		List<Map<Object, Object>> _list = new ArrayList<Map<Object, Object>>();
		for (Object domain : list) {
			Map<Object, Object> map = BeanHelper.copyNotNull2Map(domain);
			_list.add(map);
		}
		return _list;
	}

	/***
	 * 加载某个类
	 * 
	 * @param classpath
	 * @return
	 */
	public static Class loadClass(String classpath) {
		try {
			return BeanHelper.class.getClassLoader().loadClass(classpath);
		} catch (ClassNotFoundException e) {
			throw new RuntimeException(e);
		}
	}

	/***
	 * 新实例化一个对象
	 * 
	 * @param clazz
	 *            类的全路径
	 * @return
	 */
	public static Object newInstance(String clazz) {
		return newInstance(loadClass(clazz));
	}

	/***
	 * 新实例化一个对象
	 * 
	 * @param clazz
	 * @return
	 */
	public static Object newInstance(Class clazz) {
		try {
			return clazz.newInstance();
		} catch (InstantiationException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}

	/***
	 * 调用bean中的带有参数为params的method函数
	 * 
	 * @param method
	 * @param bean
	 * @param params
	 * @return
	 */
	public static Object invoke(Method method, Object bean, Object[] params) {
		try {
			return method.invoke(bean, params);
		} catch (IllegalArgumentException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} catch (InvocationTargetException e) {
			throw new RuntimeException(e.getTargetException());
		}
	}

	/****
	 * 调用bean中的带有参数为params的函数名称为methodName的函数
	 * 
	 * @param bean
	 * @param methodName
	 * @param params
	 * @return
	 */
	public static Object invoke(Object bean, String methodName, Object[] params) {
		return invoke(getMethod(bean.getClass(), methodName), bean, params);
	}

	/***
	 * 调用bean中的带有参数为params的函数名称为methodName的函数 函数名称不区分大小写
	 * 
	 * @param bean
	 * @param methodName
	 * @param params
	 * @return
	 */
	public static Object invokeIgnoreCase(Object bean, String methodName, Object[] params) {
		return invoke(getMethodIgnoreCase(bean.getClass(), methodName), bean, params);
	}

	/***
	 * 获取bean中的某列的值
	 * 
	 * @param propertyName
	 * @param bean
	 * @return
	 */
	public final static Object getPropertyValue(String propertyName, Object bean) {
		if (bean == null) {
			return null;
		}
		/**
		 * 检查有没有get方法
		 */
		String getMethodName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
		List methods = getMethods(bean.getClass(), getMethodName);
		for (int i = 0; i < methods.size(); i++) {// 大伙都先执行get函数吧
			Method getMethod = (Method) methods.get(i);
			if (methods.size() == 1 || getMethod.getParameterTypes() == null
					|| getMethod.getParameterTypes().length == 0) {
				// 调用空参数方法
				try {
					return getMethod.invoke(bean, null);
				} catch (IllegalArgumentException e) {
					throw new RuntimeException(e);
				} catch (IllegalAccessException e) {
					throw new RuntimeException(e);
				} catch (InvocationTargetException e) {
					throw new RuntimeException(e);
				}
			}
		}

		try {// 执行完成，获取当前Field中的值
			Field field = getField(bean.getClass(), propertyName);
			if (!field.isAccessible()) {
				field.setAccessible(true);
			}
			return field.get(bean);
		} catch (SecurityException e) {
			throw new RuntimeException(e);
		} catch (IllegalArgumentException e) {
			throw new RuntimeException(e);
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		}
	}

	/****
	 * 是否为基础类型
	 * 
	 * @param clazz
	 * @return
	 */
	public static boolean isPrimitiveType(Class clazz) {
		List list = new ArrayList();
		list.add(Boolean.class);
		list.add(Character.class);
		list.add(Byte.class);
		list.add(Short.class);
		list.add(Integer.class);
		list.add(Long.class);
		list.add(Float.class);
		list.add(Double.class);
		list.add(String.class);
		list.add(Date.class);
		list.add(java.sql.Date.class);
		list.add(boolean.class);
		list.add(char.class);
		list.add(byte.class);
		list.add(short.class);
		list.add(int.class);
		list.add(long.class);
		list.add(float.class);
		list.add(double.class);
		if (list.contains(clazz)) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 过滤字段
	 * 
	 * @param source
	 * @param ignore
	 * @return
	 */
	public static Object removeIgnoreFiled(Object source, String... ignore) {
		Object target = null;
		try {
			target = source.getClass().newInstance();
			BeanUtils.copyProperties(source, target, ignore);
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
		return target;
	}

	/**
	 * 
	 * @param source
	 * @param ignore
	 * @return
	 */
	public static Map<Object, Object> copyNotNull2Map(Object source, String... ignore) {
		Object target = removeIgnoreFiled(source, ignore);
		Map<Object, Object> result = Collections.EMPTY_MAP;
		try {
			result = copyNotNull2Map(target);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}

	/** 检查当前对象是否被代理过 **/
	public static boolean isCglibObject(Object tempObj) {
		boolean flag = false;
		String name = tempObj.getClass().getSimpleName();
		/** 检查当前对象是否被 cglib 代理过*/
		if(name.indexOf("$$EnhancerByCGLIB$$" ) >= 0 ){
			flag = true;
		}
		/** 检查当前对象是否被javassist 代理*/
		if(name.indexOf("$$_jvst" ) >= 0){
			flag = true;
		}
		return flag;
	}

	public static Map<Object, Object> copyNotNulAndIgnore2Map(Object source) {
		return copyNotNull2Map(source, "create_time", "create_user_id", "sts", "limit", "start", "modify_time",
				"modify_user_id");
	}

	public static void main(String[] args) throws IntrospectionException {
		BeanInfo beanInfo = Introspector.getBeanInfo(UserEntity.class);
		PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
		for (PropertyDescriptor tempField : propertyDescriptors) {
			System.out.println(tempField.getName());
		}
		 List<UserEntity> tempList = new LinkedList<UserEntity>();
		 System.out.println(tempList.getClass());
		UserEntity domain = new UserEntity();
		 domain.setCreate_time(new Date());
		 domain.setSts("Y");
		 domain.setModify_time(new Date());
		 Map tempMap =BeanHelper.copyNotNulAndIgnore2Map(domain);
		 System.out.println(tempMap.get("name"));
		 System.out.println(JsonUtils.bean2Json(tempMap));
	}
}
